﻿/* Author:
 *  Andrea Vandin
 *  Andrea Russino
 */ 

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Net;
using System.Windows.Forms;
using CompactFramework.Utilities.Localization;



namespace TripLOAMobile
{
    public partial class Login : LocalizedForm
    {
        private string[] userNames;
        private bool[] arePwdSaved;
        private bool loadUserNames;

        private AnimationControl animation;

        private Bitmap doubleBuffer;

        /// <summary>
        /// Set up screen when there is (or is not) the keyboard
        /// </summary>
        private void ReorganizePresentation()
        {
            using(Graphics g = Graphics.FromImage(doubleBuffer))
            {
                Rectangle src = new Rectangle(0, 0, Properties.Resources.logoVespa.Width, Properties.Resources.logoVespa.Height);
                Rectangle dest = new Rectangle(3, 2, src.Width, src.Height);

                if (sip.Enabled)
                {
                    int delta = chkBoxPwd.Bottom - sip.VisibleDesktop.Height;
                    if (delta > 0)
                    {
                        lblUser.Top -= delta;
                        txtBoxUser.Top -= delta;
                        listaUserName.Top -= delta;
                        lblPwd.Top -= delta;
                        txtBoxPwd.Top -= delta;
                        chkBoxPwd.Top -= delta;
                        dest.Height = src.Height - delta;
                    }
                }
                else
                {
                    //Ripristina i controlli nelle posizioni definite dalla initializeComponent

                    // lblUser
                    this.lblUser.Location = new System.Drawing.Point(2, 175);
                    //this.lblUser.Size = new System.Drawing.Size(87, 20);
                    // lblPwd
                    this.lblPwd.Location = new System.Drawing.Point(2, 202);
                    //this.lblPwd.Size = new System.Drawing.Size(60, 20);
                    // txtBoxPwd
                    this.txtBoxPwd.Location = new System.Drawing.Point(95, 202);
                    //this.txtBoxPwd.Size = new System.Drawing.Size(133, 21);
                    // listaUserName
                    this.listaUserName.Location = new System.Drawing.Point(95, 175);
                    //this.listaUserName.Size = new System.Drawing.Size(133, 22);
                    // txtBoxUser
                    this.txtBoxUser.Location = new System.Drawing.Point(97, 176);
                    //this.txtBoxUser.Size = new System.Drawing.Size(116, 18);
                    // chkBoxPwd
                    this.chkBoxPwd.Location = new System.Drawing.Point(66, 227);
                    //this.chkBoxPwd.Size = new System.Drawing.Size(162, 20);
                }
                
                g.Clear(BackColor);
                    g.DrawImage(Properties.Resources.logoVespa, dest, src, GraphicsUnit.Pixel);
            }
        }

        #region animation
        private Timer myTimer;
        /*private System.Threading.Timer stateTimer;
        private System.Threading.TimerCallback timerDelegate;
        private System.Threading.AutoResetEvent autoEvent;
        private delegate void makeAnimationDelegate();*/
        private int textualAnimation;
        #endregion

        public Login()
        {
            InitializeComponent();

            doubleBuffer = new Bitmap(sip.VisibleDesktop.Width, sip.VisibleDesktop.Height);
            ReorganizePresentation();

            #region textual animation
            myTimer = new Timer();
            myTimer.Tick += new EventHandler(TimerEvent);
            myTimer.Interval = 1000;
            myTimer.Enabled = false;
            this.textualAnimation = 0;
            /*
             * // Create the delegate that invokes methods for the timer.
            timerDelegate = new System.Threading.TimerCallback(this.timerEventHandler);
            autoEvent = new System.Threading.AutoResetEvent(false);
            autoEvent.Reset();*/
            #endregion

            #region creation of the control for the animation
            animation = new AnimationControl();
            int x = this.Width / 2 - animation.Width / 2;
            int y = this.Height / 2 - animation.Height / 2;
            animation.Location = new Point(x, y);
            this.Controls.Add(animation);
            animation.BringToFront();
            #endregion

            loadUserNames = true;
            UpdateResources();
        }

        #region start/stop animation
        delegate void animationDel();

        /// <summary>
        /// Stops the transition animation
        /// </summary>
        private void stopAnimation()
        {
            foreach (Control c in this.Controls)
            {
                c.Enabled = true;
            }
            this.menuItem1.Enabled = true;
            //this.menuItem2.Enabled = true;
            this.animation.StopAnimation();
        }

        /// <summary>
        /// Starts the transition animation
        /// </summary>
        private void startAnimation()
        {
            foreach (Control c in this.Controls)
            {
                c.Enabled = false;
            }
            this.statusLabel.Enabled = true;
            this.menuItem1.Enabled = false;
            //this.menuItem2.Enabled = false;
            this.animation.StartAnimation();
            this.AutoScroll = false;
        }
        #endregion

        /// <summary>
        /// Get profiles when the form is active
        /// </summary>
        /// <param name="e"></param>
        protected override void OnActivated(EventArgs e)
        {
            if (loadUserNames)
            {
                loadUserNames = false;
                Welcome.rrp.GetProfiles(out userNames, out arePwdSaved);
                listaUserName.DataSource = userNames;
                txtBoxUser.Text = listaUserName.Text;
            }
            base.OnActivated(e);
        }

        //protected override void OnPaintBackground(PaintEventArgs e) { }

        /// <summary>
        /// Handle paint event
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            WinAPI.ShowDoneButton(this.Handle, false);

            using (Graphics g = e.Graphics)
                g.DrawImage(doubleBuffer, 0, 0);

            base.OnPaint(e);
        }

        /// <summary>
        /// Execute Login
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuItem1_Click(object sender, EventArgs e)
        {
            this.setStatusLabel(0);

            if ((txtBoxPwd.Text == RemoteResourceProvider.standardPassword) && ((arePwdSaved[listaUserName.SelectedIndex])))
            {
                this.startAnimation();
                Welcome.rrp.SendLoginRequest(txtBoxUser.Text, this, rrp_LoginResponseReceived);
            }
            else if (CheckTexture.CheckLogIn(txtBoxUser, txtBoxPwd))
            {//login senza pwd salvata
                this.startAnimation();
                Welcome.rrp.SendLoginRequest(txtBoxUser.Text, txtBoxPwd.Text, chkBoxPwd.Checked, this, rrp_LoginResponseReceived);   
            }
            else
            {
                this.setStatusLabel(5);//prima c'era 1(fa sparire la label) Vandin
            }
        }

        #region LoginResponseHandling
        private void rrp_LoginResponseReceived(RemoteResourceProvider.LoginEventArgs e)
        {
            this.stopAnimation();
            if (e.Succeed)
            {
                this.setStatusLabel(1);
                loadUserNames = true;
                AnimationControl.USESTANDARDAPPLICATIONANIMATION = Welcome.rrp.GetUserAnimationTheme();
                if (Welcome.rrp.GetUserLanguage() != null)
                {
                    ResourceManager.Instance.Culture = new System.Globalization.CultureInfo(Welcome.rrp.GetUserLanguage());
                }
                Welcome.rrp.RememberSettingsAtLoginTime();
                this.Close();
            }
            else
            {
                if (e.Status == ResourceManager.Instance.GetString(RemoteResourceProvider.connErr) ||
                    e.Status == ResourceManager.Instance.GetString(RemoteResourceProvider.serverErr))
                {
                    this.setStatusLabel(2);
                }
                else
                {
                    this.setStatusLabel(3);
                    this.txtBoxUser.BackColor = System.Drawing.Color.FromArgb(255, 98, 102);
                    this.txtBoxPwd.BackColor = System.Drawing.Color.FromArgb(255, 98, 102);
                    this.txtBoxUser.Text = "";
                    this.txtBoxPwd.Text = "";
                }
            }
        }
        #endregion

        /// <summary>
        /// Sets text in the label that shows login status
        /// </summary>
        /// <param name="what"></param>
        private void setStatusLabel(int what)
        {
            switch (what)
            {
                case 0:
                    this.statusLabel.ForeColor = Color.Black;
                    this.statusLabel.Text = ResourceManager.Instance.GetString("Login_status_sending");
                    this.statusLabel.Visible = true;
                    #region animation
                    this.textualAnimation = 0;
                    //autoEvent.Set();
                    //this.stateTimer = new System.Threading.Timer(timerDelegate, this.autoEvent, 0, 1000);
                    this.myTimer.Enabled = true;
                    #endregion
                    break;
                case 1:
                    
                    this.statusLabel.Visible = false;
                    #region animation
                    this.myTimer.Enabled = false;
                   /* this.autoEvent.Reset();
                    this.stateTimer.Dispose();*/
                    #endregion
                    break;
                case 2:
                    #region animation
                    this.myTimer.Enabled = false;
                    #endregion
                    this.statusLabel.ForeColor = System.Drawing.Color.FromArgb(254, 98, 102);
                    this.statusLabel.Text = ResourceManager.Instance.GetString("Login_status_connErr");
                    this.statusLabel.Visible = true;
                    break;
                case 3:
                    this.statusLabel.ForeColor = System.Drawing.Color.FromArgb(254, 98, 102);
                    #region animation
                    this.myTimer.Enabled = false;
                    #endregion
                    this.statusLabel.Text = ResourceManager.Instance.GetString("Login_status_failed");
                    this.statusLabel.Visible = true;
                    break;
                case 4:
                    #region animation
                    if (this.textualAnimation == 4)
                    {
                        this.statusLabel.Text = ResourceManager.Instance.GetString("Login_status_sending");
                        this.textualAnimation = 0;
                    }
                    else
                    {
                        this.statusLabel.Text += ".";
                        this.textualAnimation++;
                    }
                    #endregion
                    break;
                case 5:
                    this.statusLabel.ForeColor = System.Drawing.Color.FromArgb(254, 98, 102);
                    #region animation
                    this.myTimer.Enabled = false;
                    #endregion
                    this.statusLabel.Text = ResourceManager.Instance.GetString("Login_status_chars");
                    this.statusLabel.Visible = true;
                    break;
                    
            }
            this.statusLabel.Invalidate();
            this.statusLabel.Update();
        }

        /// <summary>
        /// If user selects a different username from the list of saved username,
        /// it checks if a saved password exists and, eventually, adds it to the textBox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            txtBoxUser.ForeColor = Color.Black;
            txtBoxUser.BackColor = Color.White;
            txtBoxUser.Text = listaUserName.Text;
            if (arePwdSaved[listaUserName.SelectedIndex])
            {
                txtBoxPwd.Text = RemoteResourceProvider.standardPassword;
                txtBoxPwd.Enabled = false;
                chkBoxPwd.Checked = true;
                chkBoxPwd.Enabled = false;
            }
            else
            {
                txtBoxPwd.Enabled = true;
                chkBoxPwd.Enabled = true;
                txtBoxPwd.Text = "";
            }
        }

        /// <summary>
        /// If the user inserts manually his username and the username is in the saved list,
        /// it checks if a saved password exists and, eventually, adds it to the textBox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBoxUser_TextChanged(object sender, EventArgs e)
        {
            
            if (listaUserName.Items.Contains(txtBoxUser.Text))
            {
                listaUserName.SelectedIndex = listaUserName.Items.IndexOf(txtBoxUser.Text);
                if (arePwdSaved[listaUserName.SelectedIndex])
                {
                    txtBoxPwd.BackColor = Color.White;
                    txtBoxPwd.Text = RemoteResourceProvider.standardPassword;
                    txtBoxPwd.Enabled = false;
                    chkBoxPwd.Checked = true;
                    chkBoxPwd.Enabled = false;
                }
                else
                {
                    txtBoxPwd.Text = "";
                    txtBoxPwd.Enabled = true;
                    chkBoxPwd.Checked = false;
                    chkBoxPwd.Enabled = true;
                }
            }
            else
            {
                txtBoxPwd.Enabled = true;
                //chkBoxPwd.Checked = false;
                chkBoxPwd.Enabled = true; 
                txtBoxPwd.Text = "";//l'ho rimesso temporaneamente per risolvere un bug (Vandin)
            }
            //txtBoxPwd.Text = (!listaUserName.Items.Contains(txtBoxUser.Text))&&() ? "" : RemoteResourceProvider.standardPassword; ////semmai da porre come costante da qualche parte;
        }

        /// <summary>
        /// If the textBox for username gets focus,
        /// it shows a keyboard
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBoxUser_GotFocus(object sender, EventArgs e)
        {
            txtBoxUser.Text = "";
            txtBoxUser.ForeColor = Color.Black;
            txtBoxUser.BackColor = Color.White;

            //Shows the INPUT_PANEL
            sip.Enabled = true;
        }

        /// <summary>
        /// if the textBox for password gets focus,
        /// it shows a keybord
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBoxPwd_GotFocus(object sender, EventArgs e)
        {
            txtBoxPwd.PasswordChar = '*';
            //txtBoxPwd.Text = "";
            txtBoxPwd.ForeColor = Color.Black;
            txtBoxPwd.BackColor = Color.White;

            //Shows the INPUT_PANEL
            sip.Enabled = true;
        }

        /// <summary>
        /// When the textBox for username losts focus,
        /// the keyboard disappears
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBox_LostFocus(object sender, EventArgs e)
        {
            //Hides the INPUT_PANEL
            sip.Enabled = false;
        }

        /// <summary>
        /// When the keyboard is enabled/disabled
        /// the screen must be repainted
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sip_EnabledChanged(object sender, EventArgs e)
        {
            ReorganizePresentation();
            Invalidate();
            Update();
        }

        #region animation
        public void TimerEvent(object source, EventArgs e)
        {
            this.setStatusLabel(4);
        }
        #endregion

        /*
        public void timerEventHandler(Object stateInfo)
        {
            System.Diagnostics.Debug.WriteLine("prima di waitOne");
            this.autoEvent.WaitOne();
            this.autoEvent.Set();
            System.Diagnostics.Debug.WriteLine("dopo di waitOne");
            this.statusLabel.Invoke(new makeAnimationDelegate(this.makeAnimation));
            System.Diagnostics.Debug.WriteLine("dopo di invoke");
            
        }

        public void makeAnimation()
        {
            System.Diagnostics.Debug.WriteLine("!!!!!!!!!!!!!!!!!!!!testo attuale="+this.statusLabel.Text);
            if (this.animation == 4)
            {
                this.statusLabel.Text = "Sending request";
                this.animation = 0;
            }
            else
            {
                this.statusLabel.Text += ".";
                this.animation++;
            }
            
            this.statusLabel.Invalidate();
            this.statusLabel.Update();
        }*/
    }
}